package Infoclient;

import Protocol.ClientObject;
import Protocol.ComProtocol;
import Protocol.ReturnObject;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.*;

/**
 * De klasse waar de GUI wordt opgebouwd
 * @author Erik uitenbroek, Michael Stevens
 * @since 15-05-2012
 */
public class GUI extends JFrame implements ActionListener{
    
    //Variabelen van de tabs
    private JTabbedPane tabbedPane;
    private JPanel tabLogin;
    private JPanel tabQuery;
    private JPanel tabTable;   
    private JScrollPane sbPie;
    private JScrollPane sbBar;
    private Piechart pie;
    private BarChartPanel bar;   
    private JPanel tabHelp;
    
    //Attributen van het log in tab
    private JLabel labelLogin = new JLabel("Log in");
    private JLabel labelUsername = new JLabel("Username:");
    private JLabel labelPassword = new JLabel("Password:");
    private JTextField fieldUsername;
    private JPasswordField fieldPassword;
    private JButton buttonLogin = new JButton("Log in");
    //private boolean loggedIn = false;
    
    //Attributen van het query selection tab;
    private JLabel labelQuery = new JLabel("Query selection");
    private JButton buttonSelection1 = new JButton("Haal data op");
    private JButton buttonLogout = new JButton("Logout");
    private JComboBox jCombo;
    private boolean queryPerf = false;
    //private boolean qSelected = false;
    
    //Attributen van het table tab
    private JLabel labelTable = new JLabel("Table");
    private JTable table = new JTable();
    private JScrollPane scrollBar;
    private Table t = new Table();  
    
    //Attributen van het help tab
    private JLabel labelHelp = new JLabel("Help");
    private JTextArea fieldHelp = new JTextArea();
       
    private Infoclient ic;    
    
    //Constructor
    public GUI(Infoclient ic){
        this.ic = ic;
        
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Standaard schermgegevens aanmaken
        setTitle("Infoclient");
        setSize(480, 480);
        setBackground(Color.WHITE);
        setResizable(false);
        
        //Dit zorgt ervoor dat de juiste Tab (de tab waarop geklikt is) wordt weergeven
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BorderLayout());
        getContentPane().add(topPanel);        
        
        //Het aanroepen van de functies die de tabs aanmaken (in deze functies is het "subscherm" opgebouwd
        createLoginTab();
        createQueryTab();
        createTableTab();
        createPieTab();
        createBarTab();
        createHelpTab();
       
        //De tabbladbar aanmaken
        tabbedPane = new JTabbedPane();
        tabbedPane.addTab("Log in", tabLogin);
        tabbedPane.addTab("Query Selection", tabQuery);
        tabbedPane.addTab("Table", tabTable);
        tabbedPane.addTab("Pie chart", sbPie);
        tabbedPane.addTab("Bar chart", sbBar);
        tabbedPane.addTab("Help", tabHelp);
        topPanel.add(tabbedPane, BorderLayout.CENTER);
       
        //Zorgt ervoor dat de tabbladen die nog niet weergeven mogen worden, disabled zijn
        tabbedPane.setEnabledAt(1, false);
        tabbedPane.setEnabledAt(2, false);
        tabbedPane.setEnabledAt(3, false);
        tabbedPane.setEnabledAt(4, false);
       
        //Action Listeners toevoegen
        buttonLogin.addActionListener(this);
        buttonLogout.addActionListener(this);
        buttonSelection1.addActionListener(this);
        
        // kijk of de gebruiker is ingelogd zo ja log dan uit bij het sluiten van applicatie
        this.addWindowListener(new WindowAdapter() {            
            public void windowClosing(WindowEvent e) {                   
                if(getIc().getAuth().isLoggedIn()){   
                    getIc().getAuth().logOut();
                }
            }
        });
        
        setVisible(true);
       
    }
    
    /**
    * Methode om het login tab aan te maken
    * @author Erik uitenbroek
    * @since 19-05-2011
    */
    public void createLoginTab(){
        //Eerst wordt een nieuw Jpanel aangemaakt, deze is zonder layout, alles wordt dus met coordinaten geplaatst
        tabLogin = new JPanel();
        tabLogin.setLayout(null);
        
        //Label van log in scherm wordt hier toegevoegd
        labelLogin.setBounds(10, 10, 160, 20);
        tabLogin.add(labelLogin);
        
        //Label van username textfield wordt hier toegevoegd
        labelUsername.setBounds(10, 40, 65, 20);
        tabLogin.add(labelUsername);
        
        //Label van password textfield wordt hier toegevoegd
        labelPassword.setBounds(10, 70, 65, 20);
        tabLogin.add(labelPassword);
        
        //Hier wordt het textfield van de username toegevoegd
        fieldUsername = new JTextField(5);
        getFieldUsername().setBounds(80, 40, 100, 20);
        tabLogin.add(getFieldUsername());
        
        //Hier wordt het textfield van het password toegevoegd
        fieldPassword = new JPasswordField(5);
        getFieldPassword().setBounds(80, 70, 100, 20);
        tabLogin.add(getFieldPassword());
        
        //Log in knop wordt hier toegevoegd
        buttonLogin.setBounds(10,100,160,30);
        tabLogin.add(buttonLogin);
    }
    
    /**
    * Methode om het query tab aan te maken
    * @author Erik uitenbroek
    * @since 19-05-2011
    */
    public void createQueryTab(){
        //Eerst wordt een nieuw Jpanel aangemaakt, deze is zonder layout, alles wordt dus met coordinaten geplaatst
        tabQuery = new JPanel();
        tabQuery.setLayout(null);
        
        //Toevoegen van de querylabel
        labelQuery.setBounds(10, 10, 160, 20);
        tabQuery.add(labelQuery);
        
        //Toevoegen van selectie knop 1
        buttonSelection1.setBounds(10, 40, 100, 40);
        tabQuery.add(buttonSelection1);
        
        //toevoegen van loguit knop
        buttonLogout.setBounds(10, 90, 100, 40);
        tabQuery.add(buttonLogout);
        
    }
    
    /**
    * Methode om het tabel tab aan te maken
    * @author Erik uitenbroek
    * @since 19-05-2011
    */
    public void createTableTab(){
        //Eerst wordt een nieuw Jpanel aangemaakt, deze is zonder layout, alles wordt dus met coordinaten geplaatst
        tabTable = new JPanel();
        tabTable.setLayout(null);
        
        //Toevoegen van de table label
        labelTable.setBounds(10, 10, 160, 20);
        tabTable.add(labelTable);        
       
        //Toevoegen van de table
        table.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); //border wordt aangemaakt voor de scrollbar        
        
    }
    
   /**
    * Methode om het taartdiagram tab aan te maken
    * @author Erik uitenbroek
    * @since 19-05-2011
    */
    public void createPieTab(){
        //Eerst wordt een nieuw Jpanel aangemaakt, deze is zonder layout, alles wordt dus met coordinaten geplaatst
        pie = new Piechart(ic);
        pie.setPreferredSize(new Dimension(480, 2000));
        sbPie = new JScrollPane(pie);
        sbPie.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        sbPie.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    }
    
    /**
    * Methode om het staafgrafiek tab aan te maken
    * @author Erik uitenbroek
    * @since 19-05-2011
    */
    public void createBarTab(){
        //Eerst wordt een nieuw Jpanel aangemaakt, deze is zonder layout, alles wordt dus met coordinaten geplaatst
        bar = new BarChartPanel(ic);
        bar.setLayout(null);
        bar.setPreferredSize(new Dimension(10000, 0));
        sbBar = new JScrollPane(bar);
        sbBar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        sbBar.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    }
    
    /**
    * Methode om het help tab aan te maken
    * @author Erik uitenbroek
    * @since 19-05-2011
    */
    public void createHelpTab(){
        //Eerst wordt een nieuw Jpanel aangemaakt, deze is zonder layout, alles wordt dus met coordinaten geplaatst
        tabHelp = new JPanel();
        tabHelp.setLayout(null);
                
        //Toevoegen van de help label
        labelHelp.setBounds(10, 10, 160, 20);
        tabHelp.add(labelHelp);
        
        //Hier wordt de textarea aangemaakt, dit is voor de properties
        fieldHelp.setEditable(false);
        fieldHelp.setText("Hier komt de help tekst te staan, deze tekst wordt automatisch afgebroken en de scrollbar functioneert ook automatisch");
        fieldHelp.setLineWrap(true);
        fieldHelp.setWrapStyleWord(true);
        fieldHelp.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); //border wordt aangemaakt voor de scrollbar
        
        //Hier wordt de scrollbar aangemaakt, het textfield wordt aan de scrollbar toegevoegd en daarna wordt deze aangemaakt
        JScrollPane scrollBar = new JScrollPane(fieldHelp);
        scrollBar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollBar.setBounds(10, 35, 450, 375);
        tabHelp.add(scrollBar);
    }
    
    /**
    * Methode om het query tabblad aan of uit te zetten
    * @author Michael Stevens
    * @since 19-05-2011
    */
    public void enableQueryTab(boolean b){
        if(b){
            getTabbedPane().setEnabledAt(1, true);
        }else{
            getTabbedPane().setEnabledAt(1, false);
        }
    }
    
    /**
    * Methode om hetlogin tabblad aan en uit te zetten
    * @author Michael Stevens
    * @since 19-05-2011
    */
    public void enableLoginTab(boolean b){
        if(b){
            getTabbedPane().setEnabledAt(0, true);
        }else{
            getTabbedPane().setEnabledAt(0, false);
        }
    }
    
    /**
    * Methode om de tabbladen voor het weergeven van de data aan of uit te zettten
    * @author Michael Stevens
    * @since 19-05-2011
    */
    public void enableTableTabs(boolean b){
        if(b){
            getTabbedPane().setEnabledAt(2, true);
            getTabbedPane().setEnabledAt(3, true);
            getTabbedPane().setEnabledAt(4, true);
        }else{
            getTabbedPane().setEnabledAt(2, false);
            getTabbedPane().setEnabledAt(3, false);
            getTabbedPane().setEnabledAt(4, false);
        }
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()== buttonLogin){
            getIc().getAuth().logIn(getFieldUsername().getText(), getFieldPassword().getText());            
        }else if(e.getSource() == buttonSelection1){
            if(queryPerf){
                tabTable.remove(scrollBar);
                queryPerf = false;
            }            
            pie.verwerkReturnObject(getIc().getAuth().excecuteQuery(jCombo.getSelectedIndex()));            
            bar.makeBarChart("Bar Chart", getIc().getAuth().excecuteQuery(jCombo.getSelectedIndex()));            
            
            
            scrollBar = new JScrollPane(t.createTable(getIc().getAuth().excecuteQuery(jCombo.getSelectedIndex())));
            scrollBar.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            scrollBar.setBounds(10, 65, 450, 300);
            tabTable.add(scrollBar);
            
            queryPerf = true;            
            repaint();            
        }else if(e.getSource().equals(buttonLogout)){
            getIc().getAuth().logOut();
        }
    }
    
    
    /**
    * Methode de velden te resetten
    * @author Michael Stevens
    * @since 19-05-2011
    */
    public void clearFields(){
        fieldUsername.setText("");
        fieldPassword.setText("");
    }
    
    /**
    * Methode om een popup message te weergeven
    * @author Michael Stevens
    * @since 19-05-2011
    */
    public void showMessageD(String message){
        JOptionPane.showMessageDialog(this, message);        
    } 
    
    /**
    * Methode om een dropdown list aan te maken
    * @author Michael Stevens
    * @since 19-05-2011
    */
    public void createCombolist(String[] s){
        jCombo = new JComboBox(s);
        //tovoegen van query lijst
        jCombo.setBounds(120, 40, 200, 40);
        tabQuery.add(jCombo);          
    }
    
    /**
    * Methode om een de dropdown list te verwijderen dit voor wanneer een gebruiker uitlogt
    * en de applicatie aan laat staan om verolgens weer in te loggen hierna worden de query's weer opgehaald   
    * @author Michael Stevens
    * @since 19-05-2011
    */
    public void resetComboList(){
        tabQuery.remove(jCombo);
    }

    /**
     * @return the fieldUsername
     */
    public JTextField getFieldUsername() {
        return fieldUsername;
    }

    /**
     * @return the fieldPassword
     */
    public JPasswordField getFieldPassword() {
        return fieldPassword;
    }
    
    /**
     * @return the tabbedPane
     */
    public JTabbedPane getTabbedPane() {
        return tabbedPane;
    }

    /**
     * @return the ic
     */
    public Infoclient getIc() {
        return ic;
    }

    /**
     * @return the bar
     */
    public BarChartPanel getBar() {
        return bar;
    }
    
    /**
     * @return the pie
     */
    public Piechart getPie() {
        return pie;
    }    
    

    /**
     * @return the sbBar
     */
    public JScrollPane getSbBar() {
        return sbBar;
    }
}
